﻿using Com.Lancetinc.Evs.Helpers;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Com.Lancetinc.Evs.Cameras
{
    public static class WhiteBalanceHelper
    {
        private static readonly NLog.ILogger logger = NLog.LogManager.GetCurrentClassLogger();

        public static bool WriteSettingToDevice(int deviceIndex)
        {
            var typeCode = ActiveApp.Instance.GetEndoscopicTypeCode();
            if (typeCode == null)
            {
                return false;
            }
            var value = WhiteBalanceConfigHelper.GetValue(typeCode);
            if (value == null)
            {
                value = WhiteBalanceConfigHelper.GetDefaultValue(typeCode);
            }
            if (value == null)
            {
                return false;
            }

            var props = CameraProps.ALL.Where(x => x.Category == CameraPropCategory.WhiteBalance);
            if (logger.IsDebugEnabled)
            {
                logger.Debug("WhiteBalance: " + string.Join("; ", props.Select(x => x.ToString())));
            }
            foreach (var prop in props)
            {
                SetPropValue(prop, value);
                RclWriteMem(deviceIndex, prop);
            }

            return true;
        }

        public static bool InitializeProps(int deviceIndex, IEnumerable<CameraProp> props)
        {
            var typeCode = ActiveApp.Instance.GetEndoscopicTypeCode();
            if (typeCode == null)
            {
                return false;
            }
            var value = WhiteBalanceConfigHelper.GetValue(typeCode);
            if (value == null)
            {
                value = WhiteBalanceConfigHelper.GetDefaultValue(typeCode);
            }
            if (value == null)
            {
                foreach (var prop in props)
                {
                    ushort regAddr = (ushort)prop.PropId;
                    byte regVal = 0;
                    HCameraLib.hRclReadMem(deviceIndex, regAddr, ref regVal);
                    prop.Value = regVal;
                }
                return true;
            }
            if (logger.IsDebugEnabled)
            {
                logger.Debug("WhiteBalance: " + string.Join("; ", props.Select(x => x.ToString())));
            }
            foreach (var prop in props)
            {
                SetPropValue(prop, value);
                RclWriteMem(deviceIndex, prop);
            }
            return true;
        }

        public static void SaveProp(int deviceIndex, CameraProp newProp, IEnumerable<CameraProp> allProps)
        {
            var typeCode = ActiveApp.Instance.GetEndoscopicTypeCode();
            if (typeCode == null)
            {
                // 内窥镜未连接，不可设置白平衡参数
                throw new ApplicationException(I18nHelper.Default.GetMessage("CannotSetWhiteBalanceParameterBecauseofEndoscopeNotConnected"));
            }

            RclWriteMem(deviceIndex, newProp);

            WhiteBalanceValue value = new WhiteBalanceValue();
            foreach (CameraProp prop in allProps)
            {
                SetWhiteBalanceValue(value, prop);
            }
            SetWhiteBalanceValue(value, newProp);

            WhiteBalanceConfigHelper.SaveValue(typeCode, value);
        }

        private static void RclWriteMem(int deviceIndex, CameraProp prop)
        {
            ushort regAddr = (ushort)prop.PropId;
            byte regVal = (byte)prop.Value;
            HCameraLib.hRclWriteMem(deviceIndex, regAddr, regVal);
        }

        private static void SetPropValue(CameraProp prop, WhiteBalanceValue value)
        {
            CameraPropWhiteBalance wb = (CameraPropWhiteBalance)prop.PropId;
            if (wb == CameraPropWhiteBalance.R)
            {
                prop.SafeSetValue(value.R);
            }
            else if (wb == CameraPropWhiteBalance.RGain)
            {
                prop.SafeSetValue(value.RGain);
            }
            else if (wb == CameraPropWhiteBalance.B)
            {
                prop.SafeSetValue(value.B);
            }
            else if (wb == CameraPropWhiteBalance.BGain)
            {
                prop.SafeSetValue(value.BGain);
            }
            else if (wb == CameraPropWhiteBalance.G)
            {
                prop.SafeSetValue(value.G);
            }
            else if (wb == CameraPropWhiteBalance.GGain)
            {
                prop.SafeSetValue(value.GGain);
            }
        }

        private static void SetWhiteBalanceValue(WhiteBalanceValue value, CameraProp prop)
        {
            CameraPropWhiteBalance wb = (CameraPropWhiteBalance)prop.PropId;
            var propValue = (byte)prop.Value;
            if (wb == CameraPropWhiteBalance.R)
            {
                value.R = propValue;
            }
            else if (wb == CameraPropWhiteBalance.RGain)
            {
                value.RGain = propValue;
            }
            else if (wb == CameraPropWhiteBalance.B)
            {
                value.B = propValue;
            }
            else if (wb == CameraPropWhiteBalance.BGain)
            {
                value.BGain = propValue;
            }
            else if (wb == CameraPropWhiteBalance.G)
            {
                value.G = propValue;
            }
            else if (wb == CameraPropWhiteBalance.GGain)
            {
                value.GGain = propValue;
            }
        }
    }
}
